package com.foreverwin.mes.lims.service.impl;

import com.baomidou.mybatisplus.mapper.Wrapper;
import com.foreverwin.mes.common.constants.HandleBOConstants;
import com.foreverwin.mes.common.enums.HandleEnum;
import com.foreverwin.mes.core.base.FrontPage;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.foreverwin.mes.core.exception.BusinessException;
import com.foreverwin.mes.core.utils.StringUtils;
import com.foreverwin.mes.lims.dto.InspectExecDto;
import com.foreverwin.mes.lims.mapper.InspectExecDetailMapper;
import com.foreverwin.mes.lims.model.*;
import com.foreverwin.mes.lims.mapper.InspectExecMapper;
import com.foreverwin.mes.lims.service.InspectExecService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.foreverwin.mes.lims.service.InspectPlanDetailService;
import com.foreverwin.mes.lims.service.InspectTaskService;
import com.foreverwin.mes.lims.util.DataValueConstant;
import com.foreverwin.mes.lims.vo.ProjectArrayVo;
import com.foreverwin.mes.meapi.model.Item;
import com.foreverwin.mes.meapi.model.Sfc;
import com.foreverwin.mes.meapi.model.UserCert;
import com.foreverwin.mes.meapi.service.ItemService;
import com.foreverwin.mes.meapi.service.SfcInWorkService;
import com.foreverwin.mes.meapi.service.SfcService;
import com.foreverwin.mes.meapi.service.UserCertService;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Levy
 * @since 2020-02-28
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class InspectExecServiceImpl extends ServiceImpl<InspectExecMapper, InspectExec> implements InspectExecService {


    @Autowired
    private InspectExecMapper inspectExecMapper;
    @Autowired
    private SfcService sfcService;
    @Autowired
    private ItemService itemService;
    @Autowired
    private InspectTaskService inspectTaskService;
    @Autowired
    private InspectExecDetailMapper inspectExecDetailMapper;
    @Autowired
    InspectPlanDetailService inspectPlanDetailService;
    @Autowired
    SfcInWorkService sfcInWorkService;
    @Autowired
    UserCertService userCertService;



    @Override
    public Page<InspectExec> selectPage(FrontPage<InspectExec> frontPage, InspectExec inspectExec) {
        EntityWrapper<InspectExec> queryWrapper = new EntityWrapper<>();
        queryWrapper.setEntity(inspectExec);
        return super.selectPage(frontPage.getPagePlus(), queryWrapper);
    }

    @Override
    public List<InspectExec> selectList(InspectExec inspectExec) {
        EntityWrapper<InspectExec> queryWrapper = new EntityWrapper<>();
        queryWrapper.setEntity(inspectExec);
        return super.selectList(queryWrapper);
    }

    @Override
    public void doSave(String site, String user, String taskId, String sfc, String prodution, String step, List<Map> detail) {
        String execBo = StringUtils.genHandle(HandleBOConstants.INSPECT_EXEC_BO , site ,taskId);
        Date nowDate = new Date();
        boolean flag = true;

        String item = prodution.split("/")[0];
        String itemDesc = prodution.split("/")[1];
        Item oldItem = itemService.selectItemByCode( site , item );
        if ( oldItem == null ){
            throw BusinessException.build("物料编号【"+ item +"】不存在");
        }
        if ( !StringUtils.isBlank( sfc ) ){
            Sfc oldSfc = sfcService.selectById( StringUtils.genHandle( HandleBOConstants.SFC_BO ,site ,sfc ) );
            if ( oldSfc == null ){
                throw BusinessException.build("检验批次【"+ sfc +"】不存在");
            }
        }
        InspectTask oldInspectTask = inspectTaskService.selectOne(
                new EntityWrapper<InspectTask>()
                .eq( "TASK_ID" , taskId )
                .eq("SITE" , site)
        );
        if ( oldInspectTask == null ){
            throw BusinessException.build("检验任务【"+ taskId +"】不存在");
        }
        InspectExec inspectExec = new InspectExec();
        InspectExec oldModel = inspectExecMapper.selectById( execBo );
        if ( oldModel != null ){
            flag = false;
        }

        if ( flag ){
            inspectExec.setHandle( execBo );
            inspectExec.setSite( site );
            inspectExec.setTaskId( taskId );
            inspectExec.setItem( item );
            inspectExec.setItemDesc( itemDesc );
            inspectExec.setSfc( sfc );
            inspectExec.setCreatedUser( user );
            inspectExec.setCreatedDateTime( nowDate );
            inspectExecMapper.insert( inspectExec );
        }

        insert( execBo , detail , step );
    }

    private void insert( String execBo ,List<Map> details ,String step){
        for ( Map detail : details ){
            String paramName = (String) detail.get( "paramName" );
            String standard = (String) detail.get( "standard" );
            String sampleQty = (String) detail.get( "sampleQty" );
            String sampleQtyUnit = (String) detail.get( "sampleQtyUnit" );
            String standardMin = (String) detail.get( "standardMin" );
            String standardMax = (String) detail.get( "standardMax" ) ;
            String standardUnit = (String) detail.get( "standardUnit" );
            String inspectionParam = (String) detail.get( "inspectionParam" );
            String failed = (String) detail.get( "failed" ) ;
            String reason = (String) detail.get( "reason" ) ;
            String dataType = (String) detail.get( "dataType" ) ;

            inspectExecDetailMapper.delete(
                    new EntityWrapper<InspectExecDetail>()
                            .eq("INSPECT_EXEC_BO",execBo )
            );

            InspectExecDetail inspectExecDetail = new InspectExecDetail();
            inspectExecDetail.setHandle( StringUtils.genHandle( HandleBOConstants.INSPECT_EXEC_DETAIL_BO ,execBo ,step ) );
            inspectExecDetail.setParam( paramName );
            inspectExecDetail.setInspectStandard( standard );
            if ( !StringUtils.isBlank( sampleQty ) ){
                inspectExecDetail.setSampleQty( new BigDecimal( sampleQty ));
            }

            inspectExecDetail.setSampleUnit( sampleQtyUnit );
            if ( !StringUtils.isBlank( standardMin ) ){
                inspectExecDetail.setStandardMin( new BigDecimal( standardMin ) );
            }
            if ( !StringUtils.isBlank( standardMax ) ){
                inspectExecDetail.setStandardMax( new BigDecimal( standardMax ) );
            }

            inspectExecDetail.setStandardUnit( standardUnit );
            inspectExecDetail.setInspectParam( inspectionParam );
            inspectExecDetail.setInspectExecBo( execBo );
            inspectExecDetail.setInspectResult( failed == "0" ? DataValueConstant.TASK_RESULT_OK : DataValueConstant.TASK_RESULT_NG );
            inspectExecDetailMapper.insert( inspectExecDetail );

        }

    }

    @Override
    public InspectExecDto doSearch(String site, String task,String user) {
        String userBo = StringUtils.genHandle( HandleBOConstants.USER_BO,site,user );
        Date now = new Date();
        InspectExecDto inspectExecDto = new InspectExecDto();
        InspectTask inspectTask = inspectTaskService.selectOne(
                new EntityWrapper<InspectTask>()
                .eq("TASK_ID",task)
                .eq("SITE",site)
        );
        if ( inspectTask == null ){
            throw BusinessException.build("任务编号【" + task +"】不存在");
        }
        String planBo = inspectTask.getPlanBo();
        String inspectType = inspectTask.getInspectType();
        //验证当前用户是否有与当前任务计划一致的证明   2020/04/08 Max
        InspectPlanDetail _inspectPlanDetail =inspectPlanDetailService.selectOne( new EntityWrapper<InspectPlanDetail>()
                .eq("PLAN_BO",planBo)
                .eq("INSPECT_TYPE",inspectType) );
        String inspectCertificate = "";
        boolean isExist = false;
        if ( _inspectPlanDetail != null ) {
            inspectCertificate = _inspectPlanDetail.getInspectCertificate();
            if ( inspectCertificate != null && !"".equals( inspectCertificate )) {
                String certificationBo = HandleBOConstants.CERTIFICATION_BO + ":" + site + "," + inspectCertificate;
                List<UserCert> userCertList = userCertService.selectList(new EntityWrapper<UserCert>().eq("USER_BO", userBo));
                for (UserCert userCert : userCertList) {
                    String certBo = userCert.getCertificationBo();
                    if (certBo.equals(certificationBo)) {
                        isExist = true;
                    }
                }
            } else {
                isExist = true;
            }
        }
        if ( !isExist ) {
            throw BusinessException.build("用户:"+user+"无当前任务的用户证明");
        }
       /* String certificationBo = HandleBOConstants.CERTIFICATION_BO+":"+site+","+inspectCertificate;
        List<UserCert> userCertList = userCertService.selectList(new EntityWrapper<UserCert>().eq("USER_BO",userBo));
        boolean isExist = false;
        for (UserCert userCert:userCertList) {
            String certBo = userCert.getCertificationBo();
            if (certBo.equals(certificationBo)) {
                isExist = true;
            }
        }
        if ( !isExist ) {
            throw BusinessException.build("用户:"+user+"无当前任务的用户证明");
        }*/
        //任务开始
        String status =  inspectTask.getTaskStatus();
        if ( DataValueConstant.TASK_STATUS_NEW_WAIT.equals( status ) ){
            throw BusinessException.build("任务未取样!不可执行。");
        }
        inspectTask.setStartTime( now );
        inspectTask.setTaskStatus( DataValueConstant.TASK_STATUS_WORK );
        inspectTaskService.updateById( inspectTask );

        inspectExecDto.setTaskNo(task);
        inspectExecDto.setStep("1");
        inspectExecDto.setProductionNo( inspectTask.getItem()+"/"+inspectTask.getItemDesc() );
        Item item = new Item();
        if ( !StringUtils.isBlank( inspectTask.getItem() ) ){
            item = itemService.selectItemByCode( site ,inspectTask.getItem()  );
            if ( item == null ){
                throw BusinessException.build("物料不存在!");
            }
        }
       // String planBo = inspectTask.getPlanBo();
        String type = inspectTask.getInspectType();

        List<InspectPlanDetail> inspectPlanDetails = inspectPlanDetailService.selectList(
                new EntityWrapper<InspectPlanDetail>()
                .eq("PLAN_BO" , planBo)
                .eq("INSPECT_TYPE" , type)
        );
        if ( !inspectPlanDetails.isEmpty() ){
           InspectPlanDetail inspectPlanDetail = inspectPlanDetails.get( 0 );
           String category = inspectPlanDetail.getCategory();
           if ( "SFC".equals( category ) ){
               String resourceBo = planBo.split( ":" )[1];
              List<Sfc> sfc = sfcInWorkService.selectSfc( resourceBo );
              if ( !sfc.isEmpty() ){
                Sfc sfc1 =  sfc.get( 0 );
                inspectExecDto.setInspectionBatch( sfc1.getSfc() );
              }
           }
        }

        List<InspectExecDetail> inspectExecDetails = inspectExecMapper.selectProjectByPlanBo( planBo , type ,task );
        List<Map> details = new ArrayList<>();
        if ( !inspectExecDetails.isEmpty() ){
            int size = inspectExecDetails.size();
            inspectExecDto.setTotal( String.valueOf( size ) );
            for ( InspectExecDetail inspectExecDetail : inspectExecDetails ){
                Map map = new HashMap();
                map.put("paramName", inspectExecDetail.getParam());
                map.put("dataType", inspectExecDetail.getDataType());
                map.put("standard",inspectExecDetail.getInspectStandard());
                if ( inspectExecDetail.getSampleQty() != null ){
                    map.put("sampleQty",inspectExecDetail.getSampleQty());
                    map.put("sampleQtyUnit",item.getUnitOfMeasure());
                }
                if ( inspectExecDetail.getStandardMin() != null ){
                    map.put("standardMin",inspectExecDetail.getStandardMin());
                    map.put("standardMax",inspectExecDetail.getStandardMax());
                    map.put("standardUnit",inspectExecDetail.getStandardUnit());
                }
                map.put("sourceData",inspectExecDetail.getSourceData());

                details.add( map );
            }

            inspectExecDto.setDetails( details );
        }

        return inspectExecDto;
    }

    @Override
    public List<ProjectArrayVo> findArrayByTask(String site, String task, String param) {
        return  inspectExecMapper.selectProjectArrayByTask( task , param ,site );

    }
}